/*******************************************************************************
* This file provides the functions for the Output Compare module.
*
* Author: Kong Wai Weng @ Cytron Technologies Sdn. Bhd.
*******************************************************************************/



#include "hal_oc.h"



/*******************************************************************************
* PUBLIC FUNCTION: vInitOc
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Initialize the Output Compare module 1 - 8 to operate in PWM mode.
*
*******************************************************************************/
void vInitOc(void)
{
	// Disable OC if enabled previously.
	CloseOC1();
	CloseOC2();
	CloseOC3();
	CloseOC4();
	CloseOC5();
	CloseOC6();
	CloseOC7();
	CloseOC8();
	
	
	
	// Configure OC interrupt.
	ConfigIntOC1(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC2(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC3(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC4(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC5(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC6(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC7(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	ConfigIntOC8(	OC_INT_OFF &		// Interrupt disabled.
					OC_INT_PRIOR_0	);	// Interrupt priority 0.
	
	
	
	// Open the OC module.
	OpenOC1(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC2(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC3(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1000,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1000	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC4(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC5(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC6(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC7(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
	
	OpenOC8(	OC_IDLE_CON &				// OC continues to operate in CPU Idle mode.
				OC_TIMER2_SRC &				// Timer 2 is the clock source for OC.
				OC_PWM_FAULT_PIN_DISABLE,	// PWM mode without fault protection.
				PULSE_WIDTH_1500,			// Next duty cycle = 1ms (1 step = 0.2us).
				PULSE_WIDTH_1500	);		// First duty cycle = 1ms (1 step = 0.2us).
}	



/*******************************************************************************
* PUBLIC FUNCTION: vUpdateServo
*
* PARAMETERS:
* ~ ucChannel	- The servo channel that we want to update.
* ~ uiValue		- The servo pulse width value in 0.2us step (Ex: 1.5ms = 7500). 
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Update the servo output.
*
*******************************************************************************/
void vUpdateServo(unsigned char ucChannel, unsigned int uiValue)
{
	// Make sure the pulse width is in valid range.
	if ((uiValue > PULSE_WIDTH_500) && (uiValue < PULSE_WIDTH_2500)) {
		switch (ucChannel) {
			case 1:
				SetDCOC1PWM(uiValue);
				break;
			case 2:
				SetDCOC2PWM(uiValue);
				break;
			case 3:
				SetDCOC3PWM(uiValue);
				break;
			case 4:
				SetDCOC4PWM(uiValue);
				break;
			case 5:
				SetDCOC5PWM(uiValue);
				break;
			case 6:
				SetDCOC6PWM(uiValue);
				break;
			case 7:
				SetDCOC7PWM(uiValue);
				break;
			case 8:
				SetDCOC8PWM(uiValue);
				break;
		}
	}
}	
